package com.weituotian.moudle.member.dao.impl;

import com.weituotian.core.jpa.domain.SimpleSpecification;
import com.weituotian.core.utils.PageInfo;
import com.weituotian.moudle.member.dao.IMemberDao;
import com.weituotian.moudle.member.entity.*;
import com.weituotian.system.dao.impl.BaseDao;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;

import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * Created by ange on 2017/2/22.
 */
@Repository
public class MemberDao extends BaseDao<Member, Integer> implements IMemberDao {

    @Override
    protected String getEntityName() {
        return "Member";
    }

    @Override
    protected String getIdFieldName() {
        return "id";
    }

    @Override
    public Member findByEmail(String email) {
        javax.persistence.Query query1 = getSession().createQuery("select member1 from Member member1 where member1.email=:email");
        query1.setParameter("email", email);
        try {
            return (Member) query1.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    public boolean checkCollect(Integer userid, Integer videoId) {
        String jpql = "select count(member1) from Member member1 left join member1.videoCollect videos where member1.id=:uid and videos.id=:vid";
        Query query = getSession().createQuery(jpql);
        query.setParameter("uid", userid);
        query.setParameter("vid", videoId);
        long count = (long) query.getSingleResult();
        return count > 0;
    }

    public List<Video> getCollects(Integer userId, PageInfo pageInfo) {
        Session session = getSession();

        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Video> cq = cb.createQuery(Video.class);

        //条件
        SimpleSpecification<Member> spec = new SimpleSpecification<Member>() {
            @Override
            public Predicate toPredicate(Root<Member> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(root.get(Member_.id), userId);
            }
        };

        Root<Member> member = applySpecificationToCriteria(spec, cb, cq);

//        Root<Member> member = cq.from(Member.class);
        Join<Member, Video> videos = member.join(Member_.videoCollect, JoinType.LEFT);
        Fetch<Video, Partition> partition = videos.fetch(Video_.partition, JoinType.LEFT);
        Fetch<Video, Member> uploader = videos.fetch(Video_.member, JoinType.LEFT);

        //条件
//        cq.where(predicate);
        cq.select(videos);
//        CompoundSelection<Tuple> tuple = cb.tuple(videos, uploader.get(Member_.name));
//        cq.select(tuple);

        TypedQuery<Video> query = session.createQuery(cq);

        //分页
        query.setFirstResult(pageInfo.getFrom());
        query.setMaxResults(pageInfo.getPagesize());

//        List<Video> result = query.getResultList();

        //查询总数
        //总数
        CriteriaQuery<Long> cq2 = cb.createQuery(Long.class);

        Root<Member> root = applySpecificationToCriteria(spec, cb, cq2);
        Join<Member, Video> videos2 = root.join(Member_.videoCollect, JoinType.LEFT);

        if (cq2.isDistinct()) {
            cq2.select(cb.countDistinct(videos2.get(Video_.id)));
        } else {
            cq2.select(cb.count(videos2.get(Video_.id)));
        }
        Long total = executeCountQuery(session.createQuery(cq2));
        pageInfo.setTotal(total.intValue());

        //结果list
        List<Video> result = total > pageInfo.getFrom() ? query.getResultList() : Collections.<Video>emptyList();

        /*CriteriaQuery<Long> queryCount = cb.createQuery(Long.class);
        Root<Member> member1 = queryCount.from(Member.class);
        //条件
        cq.where(predicate);
        queryCount.select(cb.count(member1.get(Member_.videoCollect)));
        Query<Long> query1 = session.createQuery(queryCount);

        Long total = executeCountQuery(query1);
        pageInfo.setTotal(total.intValue());*/

        return result;
        /*String jpql = "select videos from Member member1 left join member1.videoCollect videos where member1.id=:uid";
        Query query = getSession().createQuery(jpql);
        query.setParameter("uid", userId);
        //分页
        query.setFirstResult(pageInfo.getFrom());
        query.setMaxResults(pageInfo.getPagesize());

        query.getResultList();*/
    }

    public boolean checkStar(Integer cur, Integer target) {
        String jpql = "select count(member1) from Member member1 left join member1.memberFollows follow1 where member1.id=:cid and follow1.id =:tid";
        Query query = getSession().createQuery(jpql);
        query.setParameter("cid", cur);
        query.setParameter("tid", target);
        long count = (long) query.getSingleResult();
        return count > 0;
    }

    public List<Member> getStars(Integer userId, PageInfo pageInfo) {
        String jpql = "select follow1 from Member member1 left join member1.memberFollows follow1 where member1.id=:uid";
        Query query = getSession().createQuery(jpql);
        query.setParameter("uid", userId);
        //分页
        query.setFirstResult(pageInfo.getFrom());
        query.setMaxResults(pageInfo.getPagesize());

        //总数
        String jpql1 = "select count(follow1) from Member member1 left join member1.memberFollows follow1 where member1.id=:uid";
        Query query1 = getSession().createQuery(jpql1);
        query1.setParameter("uid", userId);
        Long total = (Long) query1.getSingleResult();
        pageInfo.setTotal(total.intValue());

        //结果list
        List<Member> result = total > pageInfo.getFrom() ? query.getResultList() : Collections.<Member>emptyList();

        return result;
    }

    public Integer getNewlyMemberCount() {
        String jpql = "select count (member1) from Member member1 where member1.regDate >:yesterday";
        Query query = getSession().createQuery(jpql);
        Date today = new Date();
        Date yesterday = new Date(today.getTime() - 1000 * 60 * 60 * 24);
        query.setParameter("yesterday", yesterday);
        Long count = (Long) query.getSingleResult();
        return count.intValue();
    }

}
